/*
 * HttpRequestParser.cpp
 *
 *  Created on: 03.12.2012
 *      Author: zheka
 */

#include "HttpRequestParser.hpp"

#include <sstream>
#include <algorithm>
#include "util/ProxyException.hpp"
#include "util/StringUtils.hpp"
#include "http/HttpConstants.hpp"

HttpRequestParser::HttpRequestParser() :
		state(STATE_PARISING_HTTP_METHOD) {
}

bool HttpRequestParser::putLine(const std::string & line) {
	if (state == STATE_PARISING_HTTP_METHOD) {
		std::stringstream in(line);
		std::string httpMethod;
		if (!(in >> httpMethod)) {
			throw ProxyException(
					"[HttpRequestParser] Can't parse http method!");
		}

		// TODO: add support for all methods
		if (httpMethod != HttpConstants::HTTP_METHOD) {
			throw ProxyException(
					"[HttpRequestParser] Unsupported http method (" + httpMethod
							+ ")");
		}

		request.setHttpMethod(httpMethod);

		std::string httpQuery;
		if (!(in >> httpQuery)) {
			throw ProxyException("[HttpRequestParser] Can't parse http query!");
		}




		request.setHttpQuery(httpQuery);

		std::string httpVersion;
		if (!(in >> httpVersion)) {
			throw ProxyException(
					"[HttpRequestParser] Can't parse http version!");
		}

		if (std::find(HttpConstants::HTTP_VERSIONS.begin(), HttpConstants::HTTP_VERSIONS.end(), httpVersion) == HttpConstants::HTTP_VERSIONS.end()) {
			throw ProxyException(
					"[HttpRequestParser] Unsupported http version ("
							+ httpVersion + ")");
		}
		request.setHttpVersion(httpVersion);
		state = STATE_PARISING_HTTP_HEADERS;
		return true;
	} else if(state == STATE_PARISING_HTTP_HEADERS) {
		std::string s = StringUtils::trim(line);

			if (s.length() != 0) {
				int pos;
				if ((pos = s.find(HttpConstants::HTTP_HEADER_DELIMITER))
						== std::string::npos) {
					throw ProxyException(
							"[HttpRequestParser] Can't parse http header (" + s
									+ ")");
				}
				std::string key = s.substr(0, pos);
				std::string value = StringUtils::trim(
						s.substr(
								pos + HttpConstants::HTTP_HEADER_DELIMITER.length())); // skip ':'
				request.addHeader(key, value);

				return true;
			} else {
				state = STATE_PARISING_FINISHED;
				return false;
			}
	}

	return false;
}

HttpRequest HttpRequestParser::getHttpRequest() {
	return request;
}

